<?php

/**
 * oop基本概念
 * Created by PhpStorm.
 * User: LuckyStarD
 * Date: 17/6/20
 * Time: 下午5:48
 */


/**
 * class
 *
 * 每个类的定义都以关键字 class 开头，后面跟着类名，后面跟着一对花括号，里面包含有类的属性与方法的定义。
 * 类名可以是任何非 PHP 保留字的合法标签。一个合法类名以字母或下划线开头，后面跟着若干字母，数字或下划线。以正则表达式表示为：
 * [a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*。
 *
 * 一个类可以包含有属于自己的常量，变量（称为"属性"）以及函数（称为"方法"）。
 *
 * Example #1 简单类的定义
 */
class SimpleClass
{
    // property declaration
    public $var = 'a default value';

    public function displayVar()
    {
        // method declaration
        echo $this->var;
    }
}


/**
 * 当一个方法在类定义内部被调用时，有一个可用的伪变量 $this 。
 * $this 是一个到主叫对象的引用（通常是该方法所从属的对象，但如果是从第二个对象静态调用时也可能是另一个对象）。
 *
 * Example #2 $this 伪变量的示例
 */
class A
{
    function foo()
    {
        if (isset($this)) {
            echo '$this is defined (';
            echo get_class($this);
            echo ")\n";
        } else {
            echo "\$this is not defined.\n";
        }
    }
}


class B
{
    function bar()
    {
        // Note: the next line will issue a warning if E_STRICT is enabled.
        A::foo();
    }
}

$a = new A();
$a->foo();

// Note: the next line will issue a warning if E_STRICT is enabled.
A::foo();
$b = new B();
$b->bar();

// Note: the next line will issue a warning if E_STRICT is enabled.
B::bar();


/*以上例程会输出
$this is defined (A)
$this is not defined.
$this is defined (B)
$this is not defined.*/


/**
 * new
 *
 * 要创建一个类的实例，必须使用 new 关键字。
 * 当创建新对象时该对象总是被赋值，除非该对象定义了构造函数并且在出错时抛出了一个异常。类应该在被实例化之前定义。
 *
 * 如果在 new 之后跟着额是一个包含有类名的字符串，则该类的一个实例被创建。
 * 如果该类属于一个名字空间，则必须使用其完整名称。
 *
 * Example #3 创建一个实例
 */

$instance = new SimpleClass();

//也可以这么做
$className = 'Foo';
$instance = new $className(); //Foo();


/**
 * extends
 *
 * 一个类可以在声明中用 extends 关键字继承另一个类的方法和属性。PHP不支持多重继承，一个类只能继承一个基类。
 *
 *被继承的方法和属性可以通过用同样的名字重新声明被覆盖。但是如果父类定义方法时使用了 final，则该方法不可被覆盖。可以通过 parent:: 来访问被覆盖的方法或属性。
 *
 *当覆盖方法时，参数必须保持一致否则 PHP 将发出 E_STRICT 级别的错误信息。但构造函数例外，构造函数可在被覆盖时使用不同的参数。
 *
 * Example #6 简单的类继承
 */

class ExtendClass extends SimpleClass
{
    // Redefine the parent method
    function displayVar()
    {
        echo "Extending class\n";
        parent::displayVar();
    }
}

$extended = new ExtendClass();
$entended->displayVar();